package com.white.report.framework.read;

import lombok.Getter;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 聚合枚举
 * </p>
 *
 * @author white
 * @since 2022/1/22
 */
@Getter
public enum AggregateEnum implements AggregateFunction {

    /**
     * 求和
     */
    SUM(1, "求和") {
        @Override
        public BigDecimal count(List<BigDecimal> list) {
            BigDecimal num = BigDecimal.ZERO;
            if (list != null) {
                for (BigDecimal bigDecimal : list) {
                    if (bigDecimal != null) {
                        num = num.add(bigDecimal);
                    }
                }
            }
            return num;
        }
    },

    /**
     * 平均值
     */
    AVG(2,"平均值") {
        @Override
        public BigDecimal count(List<BigDecimal> list) {
            if (list == null || list.isEmpty()) {
                return BigDecimal.ZERO;
            }
            BigDecimal num = BigDecimal.ZERO;
            for (BigDecimal bigDecimal : list) {
                if (bigDecimal != null) {
                    num = num.add(bigDecimal);
                }
            }
            return num.divide(BigDecimal.valueOf(list.size()),2, RoundingMode.DOWN);
        }
    },

    /**
     * 平均值(不统计NULL值)
     */
    AVG_EXCLUDE_NULL(3,"平均值(不统计NULL值)") {
        @Override
        public BigDecimal count(List<BigDecimal> list) {
            if (list == null || list.isEmpty()) {
                return BigDecimal.ZERO;
            }
            BigDecimal num = BigDecimal.ZERO;
            for (BigDecimal bigDecimal : list) {
                if (bigDecimal != null) {
                    num = num.add(bigDecimal);
                }
            }
            return num.divide(BigDecimal.valueOf(list.stream().filter(Objects::nonNull).count()),2, RoundingMode.DOWN);
        }
    }
    ;

    private final Integer id;

    private final String value;

    AggregateEnum(Integer id, String value) {
        this.id = id;
        this.value = value;
    }
}
